package org.xlx.xlx_oa.role_user.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.xlx.xlx_oa.common.AuthCache;
import org.xlx.xlx_oa.common.BusinessException;
import org.xlx.xlx_oa.common.Constant;
import org.xlx.xlx_oa.role_user.convertor.RoleUserConvertor;
import org.xlx.xlx_oa.role_user.domain.*;
import org.xlx.xlx_oa.role_user.domain.dto.AdmUserDto;
import org.xlx.xlx_oa.role_user.domain.dto.SysControlDto;
import org.xlx.xlx_oa.role_user.domain.vo.AdmUserVo;
import org.xlx.xlx_oa.role_user.mapper.*;
import org.xlx.xlx_oa.utils.ThreadLocalUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

@Service
public class AdmUserService {
    private final RoleUserConvertor roleUserConvertor = RoleUserConvertor.INSTANCE;
    @Autowired
    private AdmUserMapper admUserMapper;
    @Autowired
    private AdmDepartmentMapper departmentMapper;
    @Autowired
    private AdmPositionMapper positionMapper;
    @Autowired
    private SysControlMapper sysControlMapper;
    @Autowired
    private SysUserRoleRelMapper roleRelMapper;
    @Autowired
    private AuthCache authCache;

    /**
     * 登录校验
     *
     * @param account  账户名
     * @param password 密码
     * @return 校验成功, 返回用户对象;校验失败,抛出异常
     */
    public AdmUserDto validateLogin(String account, String password) {
        if (Objects.isNull(account) || Objects.isNull(password)) {
            throw new BusinessException("100001", "validate message is empty");
        }
        QueryWrapper<AdmUser> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(AdmUser::getAccount, account);
        AdmUser user = admUserMapper.selectOne(wrapper);
        if (Objects.isNull(user)) {
            throw new BusinessException("100002", "user account is unregistered");
        }
        if (!user.getPassword().equals(password)) {
            throw new BusinessException("100003", "user password is incorrect");
        }
        user.setPassword(null);
        AdmUserDto admUserDto = roleUserConvertor.convertToUserDto(user);
        this.suppleUserDto(admUserDto);
        String token = UUID.randomUUID().toString().replace("-", "");
        authCache.setSessionData(token, JSON.toJSONString(admUserDto));
        authCache.expireSessionData(token);
        admUserDto.setToken(token);
        return admUserDto;
    }

    /**
     * 注销校验
     *
     * @return 删除redis中的token数据的结果
     */
    public Boolean validateLogout() {
        Object objToken = ThreadLocalUtil.get(Constant.TOKEN);
        String token = Objects.isNull(objToken) ? null : objToken.toString();
        AdmUser admUser = authCache.getSessionData(token);
        if (Objects.isNull(admUser)) {
            throw new BusinessException("100004", "Login verification has expired");
        }
        return authCache.deleteSessionData(token);
    }

    /**
     * 获取功能模块
     *
     * @param userId 用户id
     * @return 返回功能模块
     */
    public List<SysControlDto> getControlsByUserId(Long userId) {
        List<SysControl> sysControls = sysControlMapper.selectListByUserId(userId);
        List<SysControlDto> sysControlDtos = roleUserConvertor.convertToListSysControlDto(sysControls);
        return sysControlDtos;
    }

    /**
     * 获取leader
     *
     * @param admUser
     * @return
     */
    public AdmUser getLeader(AdmUser admUser) {
        QueryWrapper<AdmUser> queryWrapper = new QueryWrapper<>();
        if (admUser.getLevel() < 7) {
            queryWrapper.lambda()
                    .eq(AdmUser::getDepartmentId, admUser.getDepartmentId())
                    .eq(AdmUser::getLevel, 7);
        } else if (admUser.getLevel() == 7) {
            queryWrapper.lambda()
                    .eq(AdmUser::getLevel, 8);
        } else if (admUser.getLevel() == 8) {
            queryWrapper.lambda()
                    .eq(AdmUser::getLevel, 8);
        } else {
            throw new BusinessException("100005", "nonexistence user level");
        }
        AdmUser leader = admUserMapper.selectOne(queryWrapper);
        return leader;
    }

    /**
     * 获取当前用户的leader
     *
     * @return
     */
    public AdmUser getCurLeader() {
        AdmUser admUser = new AdmUser();
        Object objLevel = ThreadLocalUtil.get(Constant.LEVEL);
        Integer level = Objects.isNull(objLevel) ? null : Integer.valueOf(objLevel.toString());
        admUser.setLevel(level);
        Object objDepartmentId = ThreadLocalUtil.get(Constant.DEPARTMENTID);
        Long departmentId = Objects.isNull(objDepartmentId) ? null : Long.valueOf(objDepartmentId.toString());
        admUser.setDepartmentId(departmentId);
        AdmUser leader = this.getLeader(admUser);
        return leader;
    }

    /**
     * 根据id集合获取多个用户信息
     *
     * @return
     */
    public List<AdmUserDto> getListUsersByIds(String idStr) {
        String[] split = idStr.split(",");
        ArrayList<Long> ids = new ArrayList<>();
        for (String s : split) {
            ids.add("null".equals(s) ? null : Long.valueOf(s));
        }
        QueryWrapper<AdmUser> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(AdmUser::getId, ids);
        List<AdmUser> users = admUserMapper.selectList(wrapper);
        List<AdmUserDto> admUserDtos = roleUserConvertor.convertToUserDtoList(users);
        admUserDtos.forEach(userDto -> this.suppleUserDto(userDto));
        return admUserDtos;
    }

    /**
     * 部门或岗位是否为空
     *
     * @param user
     * @return
     */
    public Boolean checkDepartOrPositionEmpty(AdmUser user) {
        QueryWrapper<AdmUser> queryWrapper = new QueryWrapper<>();
        if (!Objects.isNull(user.getDepartmentId())) {
            queryWrapper.lambda().eq(AdmUser::getDepartmentId, user.getDepartmentId());
        }
        if (!Objects.isNull(user.getPositionId())) {
            queryWrapper.lambda().eq(AdmUser::getPositionId, user.getPositionId());
        }
        List<AdmUser> admUsers = admUserMapper.selectList(queryWrapper);
        boolean isEmpty = admUsers.size() == 0 || admUsers == null;
        return isEmpty;
    }

    /**
     * 保存
     */
    public Boolean saveEntity(AdmUserVo userVo) {
        AdmUser user = roleUserConvertor.convertVoToAdmUser(userVo);
        Long id = user.getId();
        if (Objects.isNull(id)) {
            admUserMapper.insert(user);
        } else {
            admUserMapper.updateById(user);
        }
        SysUserRoleRel rel = new SysUserRoleRel();
        rel.setRoleId(3L);
        rel.setUserId(user.getId());
        roleRelMapper.insert(rel);
        return true;
    }

    /**
     * 删除
     */
    public Boolean removeEntity(Long id) {
        return admUserMapper.deleteById(id) > 0;
    }

    /**
     * 列表
     */
    public List<AdmUserDto> getList(AdmUserVo userVo) {
        AdmUser user = roleUserConvertor.convertVoToAdmUser(userVo);
        Page<AdmUser> page = new Page<>(userVo.getPageNum(), userVo.getPageSize());
        QueryWrapper<AdmUser> wrapper = new QueryWrapper<>();
        if (!Objects.isNull(userVo.getPositionTitle())) {
            wrapper.lambda().in(AdmUser::getPositionId, this.convertPositionTitle(userVo));
        }
        if (!Objects.isNull(userVo.getDepartmentTitle())) {
            wrapper.lambda().in(AdmUser::getPositionId, this.convertDepartmentTitle(userVo));
        }
        if (!Objects.isNull(user.getAccount())) {
            wrapper.lambda().like(AdmUser::getAccount, user.getAccount());
        }
        if (!Objects.isNull(user.getFirstName())) {
            wrapper.lambda().like(AdmUser::getFirstName, user.getFirstName());
        }
        if (!Objects.isNull(user.getMiddleName())) {
            wrapper.lambda().like(AdmUser::getMiddleName, user.getMiddleName());
        }
        if (!Objects.isNull(user.getLastName())) {
            wrapper.lambda().like(AdmUser::getLastName, user.getLastName());
        }
        if (!Objects.isNull(user.getIsHire())) {
            wrapper.lambda().eq(AdmUser::getIsHire, user.getIsHire());
        }
        admUserMapper.selectPage(page, wrapper);
        List<AdmUserDto> admUserDtos = roleUserConvertor.convertToUserDtoList(page.getRecords());
        admUserDtos.forEach(userDto -> this.suppleUserDto(userDto));
        return admUserDtos;
    }

    /**
     * 详情
     */
    public AdmUserDto getDetail(Long id) {
        AdmUser user = admUserMapper.selectById(id);
        AdmUserDto admUserDto = roleUserConvertor.convertToUserDto(user);
        this.suppleUserDto(admUserDto);
        return admUserDto;
    }

    public Integer getCount(AdmUserVo userVo) {
        AdmUser user = roleUserConvertor.convertVoToAdmUser(userVo);
        QueryWrapper<AdmUser> wrapper = new QueryWrapper<>();
        if (!Objects.isNull(userVo.getPositionTitle())) {
            wrapper.lambda().in(AdmUser::getPositionId, this.convertPositionTitle(userVo));
        }
        if (!Objects.isNull(userVo.getDepartmentTitle())) {
            wrapper.lambda().in(AdmUser::getPositionId, this.convertDepartmentTitle(userVo));
        }
        if (!Objects.isNull(user.getAccount())) {
            wrapper.lambda().like(AdmUser::getAccount, user.getAccount());
        }
        if (!Objects.isNull(user.getFirstName())) {
            wrapper.lambda().like(AdmUser::getFirstName, user.getFirstName());
        }
        if (!Objects.isNull(user.getMiddleName())) {
            wrapper.lambda().like(AdmUser::getMiddleName, user.getMiddleName());
        }
        if (!Objects.isNull(user.getLastName())) {
            wrapper.lambda().like(AdmUser::getLastName, user.getLastName());
        }
        if (!Objects.isNull(user.getIsHire())) {
            wrapper.lambda().eq(AdmUser::getIsHire, user.getIsHire());
        }
        return admUserMapper.selectCount(wrapper);
    }

    /**
     * 校验原始密码是否正确
     *
     * @param old
     * @return
     */
    public Boolean checkOriginPassword(String old) {
        Object objUserId = ThreadLocalUtil.get(Constant.USERID);
        Long userId = Objects.isNull(objUserId) ? null : Long.valueOf(objUserId.toString());
        AdmUser user = admUserMapper.selectById(userId);
        return user.getPassword().equals(old);
    }

    /**
     * 修改头像
     *
     * @param path
     * @return
     */
    public Boolean updateIcon(String path) {
        Object objUserId = ThreadLocalUtil.get(Constant.USERID);
        Long userId = Objects.isNull(objUserId) ? null : Long.valueOf(objUserId.toString());
        AdmUser user = new AdmUser();
        user.setIcon(path);
        user.setId(userId);
        return admUserMapper.updateById(user) > 0;
    }

    /**
     * user补全
     *
     * @param userDto
     */
    public void suppleUserDto(AdmUserDto userDto) {
        if (!Objects.isNull(userDto.getDepartmentId())) {
            AdmDepartment department = departmentMapper.selectById(userDto.getDepartmentId());
            if (!Objects.isNull(department)) {
                userDto.setDepartmentTitle(department.getTitle());
            }
        }
        if (!Objects.isNull(userDto.getPositionId())) {
            AdmPosition position = positionMapper.selectById(userDto.getPositionId());
            if (!Objects.isNull(position)) {
                userDto.setPositionTitle(position.getTitle());
            }
        }
    }

    /**
     * 根据名字模糊查询
     * @param name
     * @return
     */
    public List<AdmUserDto> searchByName(String name){
        QueryWrapper<AdmUser> wrapper = new QueryWrapper<>();
        if (name!=null&&(!"".equals(name))){
            wrapper.lambda()
                    .like(AdmUser::getFirstName,name)
                    .or()
                    .like(AdmUser::getMiddleName,name)
                    .or()
                    .like(AdmUser::getLastName,name);
        }
        List<AdmUser> users = admUserMapper.selectList(wrapper);
        List<AdmUserDto> admUserDtos = roleUserConvertor.convertToUserDtoList(users);
        admUserDtos.forEach(userDto -> this.suppleUserDto(userDto));
        return admUserDtos;
    }

    public List<Long> convertDepartmentTitle(AdmUserVo userVo) {
        ArrayList<Long> ids = new ArrayList<>();
        if (!Objects.isNull(userVo.getDepartmentTitle())) {
            QueryWrapper<AdmDepartment> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().like(AdmDepartment::getTitle, userVo.getDepartmentTitle());
            List<AdmDepartment> admDepartments = departmentMapper.selectList(queryWrapper);
            admDepartments.forEach(department -> ids.add(department.getId()));
        }
        return ids;
    }

    public List<Long> convertPositionTitle(AdmUserVo userVo) {
        ArrayList<Long> ids = new ArrayList<>();
        if (!Objects.isNull(userVo.getPositionTitle())) {
            QueryWrapper<AdmPosition> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().like(AdmPosition::getTitle, userVo.getPositionTitle());
            List<AdmPosition> positions = positionMapper.selectList(queryWrapper);
            positions.forEach(position -> ids.add(position.getId()));
        }
        return ids;
    }
}
